/**
 * @typedef {{method:string,path:string}} Req {id} 将产生名为id的 path variable
 * @typedef {({query,body,pathVars})=>any} ReqHandle
 * @typedef {(ws:import('ws').WebSocket,req:import('express').Request)=>void} WsHandler
 */
/**
 * @type {Map<Req,ReqHandle>}
 */
const map = new Map()

/**
 *
 * @param {Req} finder
 * @param {ReqHandle} handler
 */
export function addRequest({ method, path }, handler) {
  if (/\{\}/.test(path)) {
    throw new Error('无效的path，不能含有空name的pathVariable：' + path)
  }

  method = method.toUpperCase()
  path = path.replace(/\\/g, '/')

  for (const f of map.keys()) {
    if (f.method !== method) {
      continue
    }
    const _pExp = f.path.replace(/\{.+?\}/g, '.+?')
    if (new RegExp('^' + _pExp + '$').test(path)) {
      throw new Error('已存在相同的请求签名：' + f.method + ' ' + f.path)
    }
  }

  map.set({ method, path }, handler)
}

/**
 * @returns {[Req,ReqHandle]|undefined}
 * @param {Req} req
 */
export function findReqHandler({ method, path }) {
  method = method.toUpperCase()

  for (const f of map.keys()) {
    if (f.method !== method) {
      continue
    }
    const _pExp = f.path.replace(/\{.+?\}/g, '.+?')
    if (new RegExp('^' + _pExp + '$').test(path)) {
      return [f, map.get(f)]
    }
  }
}

/**
 *
 * @param {string} path
 * @param {string} pattern
 * @returns
 */
export function getPathVariables(path, pattern) {
  const vs = path.split('/')
  const ks = pattern.split('/')
  const obj = {}
  for (let i = 0; i < ks.length; i++) {
    if (ks[i] === vs[i]) continue
    const key = ks[i].replace(/[{}]/g, '')
    obj[key] = vs[i]
  }

  return obj
}

/** @type {Map<string,WsHandler>} */
export const wsMap = new Map()

/**
 *
 * @param {string} url
 * @param {WsHandler} handler
 */
export function addWs(url, handler) {
  if (wsMap.has(url)) {
    throw new Error('已存在相同的 webSocket url 注册')
  }
  wsMap.set(url, handler)
}
